import collections
import copy

baida_table = collections.OrderedDict()
baida_eye_table = collections.OrderedDict()

for i in range(0,5):
    baida_table.setdefault(i,{})
    baida_eye_table.setdefault(i,{})

zi_table = collections.OrderedDict()
eye_zi_table = collections.OrderedDict()
for i in range(0,5):
    zi_table.setdefault(i,{})
    eye_zi_table.setdefault(i,{})

def add_key(key,baida_num,eye,value):
    if eye == True:
        if key not in eye_zi_table[baida_num]:
            eye_zi_table[baida_num].setdefault(key, [])
        eye_zi_table[baida_num][key] = value[0]
    else:
        if key not in zi_table[baida_num]:
            zi_table[baida_num].setdefault(key, [])
        zi_table[baida_num][key] = value[0]


def check_add(cards,baida_num,eye,value):
    key = 0
    for i in range(0,7):
        key = key * 10 + cards[i]

    if key == 0:
        return False

    nor_table = {}

    if eye == False:
        nor_table = baida_table[baida_num]
    else:
        nor_table = baida_eye_table[baida_num]

    if key in nor_table:
        return False

    nor_table.setdefault(key,True)

    for i in range(0,7):
        if cards[i] > 4:
            return True

    tmp_value = copy.deepcopy(value)
    maxBaiDaCard = 0
    for i in range(0, 4):
        baiDaCard = (tmp_value[0] >> (12 + i * 4)) & 0xF
        if baiDaCard > maxBaiDaCard:
            maxBaiDaCard = baiDaCard

    tmp_value[0] |= (maxBaiDaCard << 8)

    add_key(key,baida_num,eye,tmp_value)
    return True

def get_last_key_value(cards,baida_num,eye):
    key = 0
    for i in range(0,7):
        key = key * 10 + cards[i]

    if key == 0:
        return False,0

    if eye == True:
        if key in eye_zi_table[baida_num]:
            return True,eye_zi_table[baida_num][key]
        else:
            return False,0
    else:
        if key in zi_table[baida_num]:
            return True,zi_table[baida_num][key]
        else:
            return False,0


def add_not_first_time(cards,baida_num,eye,value):
    key = 0
    for i in range(0, 7):
        key = key * 10 + cards[i]

    nor_table = {}

    if eye == False:
        nor_table = baida_table[baida_num]
    else:
        nor_table = baida_eye_table[baida_num]

    for i in range(0,7):
        if cards[i] > 4:
            return True

    add_key(key,baida_num,eye,value)
    return True

def parse_table_sub(cards,baida_num,eye,value,value_count):
    tmp_value = copy.deepcopy(value)
    tmp_value_count = copy.deepcopy(value_count)
    for i in range(0,7):
        if cards[i] == 0:
            continue

        cards[i] -= 1
        tmp_value[0] |= (i + 1) << value_count[0]
        tmp_value_count[0] += 4

        if not check_add(cards, baida_num, eye, tmp_value):
            flag,last_value = get_last_key_value(cards,baida_num,eye)
            if flag == True:
                tt_value = copy.deepcopy(tmp_value)
                maxBaiDaCard = 0
                for j in range(0, 4):
                    baiDaCard = (tt_value[0] >> (12 + j * 4)) & 0xF
                    if baiDaCard > maxBaiDaCard:
                        maxBaiDaCard = baiDaCard

                tt_value[0] |= (maxBaiDaCard << 8)
                last_max_value = last_value >> 8 & 0xF
                max_value = tt_value[0] >> 8 & 0xF
                if max_value > last_max_value:
                    add_not_first_time(cards, baida_num, eye, tt_value)
            cards[i] += 1
            tmp_value = copy.deepcopy(value)
            tmp_value_count = copy.deepcopy(value_count)
            continue

        if baida_num < 4:
            parse_table_sub(cards,baida_num + 1,eye,tmp_value,tmp_value_count)

        cards[i] += 1
        tmp_value = copy.deepcopy(value)
        tmp_value_count = copy.deepcopy(value_count)


def parse_table(cards,eye,value,value_count):
    if not check_add(cards,0,eye,value):
        return
    parse_table_sub(cards,1,eye,value,value_count)

def gen_table_sub(e_list,count,eye,value,value_count):
    tmp_value = copy.deepcopy(value)
    tmp_value_count = copy.deepcopy(value_count)
    for i in range(0,7):
        if e_list[i] > 3: continue
        e_list[i] += 3

        parse_table(e_list,eye,tmp_value,tmp_value_count)

        if count < 3:
            gen_table_sub(e_list,count + 1,eye,tmp_value,tmp_value_count)

        e_list[i] -= 3

        tmp_value = copy.deepcopy(value)
        tmp_value_count = copy.deepcopy(value_count)

#   4bit  0: 对子的数量(0～7)
#   4bit  4: 对子的值(0 ~ 9)
#   4bit  8: 最大的百搭值(0 ~ 9)
#   4bit 12: 百搭的值1(0～9)
#   4bit 16: 百搭的值2(0～13)
#   4bit 20: 百搭的值3(0～13)
#   4bit 24: 百搭的值4(0～13)
def gen_table():
    e_list = [0, 0, 0, 0, 0, 0, 0]
    value = [0]
    value_count = [12]
    gen_table_sub(e_list,0,False,value,value_count)

def gen_eye_table():
    e_list = [0, 0, 0, 0, 0, 0, 0]

    for i in range(0,7):
        e_list[i] = 2
        value = [0]
        value[0] = 1 + ((i + 1) << 4) + (0 << 8)
        value_count = [12]
        parse_table(e_list,True,value,value_count)
        gen_table_sub(e_list,0,True,value,value_count)
        e_list[i] = 0

# gen_table()
# gen_eye_table()
#
# for i in range(0,5):
#     with open("E:\PythonWorkSpace\generate_list_hu\\tables\\baida_zi_table" + str(i) + ".txt","w") as file:
#         for s in zi_table[i]:
#             # ss = "baiDaZiTable[{index}].insert(std::pair<uint32_t,bool>({key},true));".format(index = i,key = s)
#             ss = "{key},{value}".format(key = s,value=zi_table[i][s])
#             file.writelines(ss + "\n")
#
# for i in range(0,5):
#     with open("E:\PythonWorkSpace\generate_list_hu\\tables\\baida_eye_zi_table" + str(i) +".txt","w") as file:
#         for s in eye_zi_table[i]:
#             # ss = "baidaEyeZiTable[{index}].insert(std::pair<uint32_t,bool>({key},true));".format(index = i,key = s)
#             ss = "{key},{value}".format(key=s,value=eye_zi_table[i][s])
#             file.writelines(ss + "\n")